package faultMethod;

import heightMap.HeightMap;
import java.util.Random;
import java.awt.Polygon;

public class FaultMethod {

	// general variables
	private HeightMap hMap;
	private int[][] map;
	private int runs;
	private int size;

	// fault-method specific variables
	private final int UPPER_LEFT_X = 0;
	private final int UPPER_LEFT_Y = 0;
	private final int UPPER_RIGHT_Y = 0;
	private final int LOWER_LEFT_X = 0;
	private int UPPER_RIGHT_X, LOWER_RIGHT_X, LOWER_LEFT_Y, LOWER_RIGHT_Y;
	private int raiseHeight;

	// Objects
	Random rand;
	Polygon a;
	Polygon b;
	int randXa, randYa, randXb, randYb;
	int[] axPoints = new int[4];
	int[] ayPoints = new int[4];
	int[] bxPoints = new int[4];
	int[] byPoints = new int[4];

	// test objects
	String msg = "";

	public FaultMethod(int size, int runs, int raiseHeight) {
		this.size = size;
		hMap = new HeightMap(size);
		map = hMap.getMap();
		this.runs = runs;
		UPPER_RIGHT_X = size - 1;
		LOWER_RIGHT_X = size - 1;
		LOWER_LEFT_Y = size - 1;
		LOWER_RIGHT_Y = size - 1;
		rand = new Random();
		this.raiseHeight = raiseHeight;
		run();
		// printMap();
		remakeMap();
	}

	private void run() {
		int random;
		for (int q = 0; q < runs; q++) {
			System.out.println("Run " + q);
			// draw the line
			// decide which end has the line drawn on it (top or left)
			// also, the points arrays have to be filled in here too
			random = rand.nextInt(2);
			// line to be drawn from top to bottom - only need to generate x
			if (random == 0) {
				randXa = rand.nextInt(size);
				randXb = rand.nextInt(size);
				msg = "top to bottom at " + randXa + "x and " + randXb + "x";
				axPoints[0] = UPPER_LEFT_X;
				axPoints[1] = randXa;
				axPoints[2] = randXb;
				axPoints[3] = LOWER_LEFT_X;
				bxPoints[0] = randXa;
				bxPoints[1] = UPPER_RIGHT_X;
				bxPoints[2] = LOWER_RIGHT_X;
				bxPoints[3] = randXb;
				ayPoints[0] = UPPER_LEFT_Y;
				ayPoints[1] = UPPER_RIGHT_Y;
				ayPoints[2] = LOWER_RIGHT_Y;
				ayPoints[3] = LOWER_LEFT_Y;
				byPoints = ayPoints.clone();
			}
			// line to be drawn left to right - only need y-coords
			else {
				randYa = rand.nextInt(size);
				randYb = rand.nextInt(size);
				msg = "left to right at " + randYa + "y and " + randYb + "y";
				axPoints[0] = UPPER_LEFT_X;
				axPoints[1] = UPPER_RIGHT_X;
				axPoints[2] = LOWER_RIGHT_X;
				axPoints[3] = LOWER_LEFT_X;
				bxPoints = axPoints.clone();
				ayPoints[0] = UPPER_LEFT_Y;
				ayPoints[1] = UPPER_RIGHT_Y;
				ayPoints[2] = randYb;
				ayPoints[3] = randYa;
				byPoints[0] = randYa;
				byPoints[1] = randYb;
				byPoints[2] = LOWER_RIGHT_Y;
				byPoints[3] = LOWER_LEFT_Y;
			}
			// create polygon with proper edges
			a = new Polygon(axPoints, ayPoints, 4);
			b = new Polygon(bxPoints, byPoints, 4);

			// determine which side to raise, other gets lowered
			random = rand.nextInt(2);

			// iterate through height map
			// TODO: Find a good way to raise / lower the height so no major
			// variance
			for (int i = 0; i < size; i++) {
				for (int j = 0; j < size; j++) {
					// raise / lower proper sides
					if (random == 0) {
						// raise a
						if (a.contains(i, j)) {
							map[i][j] += raiseHeight;
						}
					} else {
						// lower a
						if (a.contains(i, j)) {
							map[i][j] -= raiseHeight;
						}
					}
					if (random == 1) {
						// raise b
						if (b.contains(i, j)) {
							map[i][j] += raiseHeight;
						}
					} else {
						// lower b
						if (b.contains(i, j)) {
							map[i][j] -= raiseHeight;
						}
					}

				}
			}

		}
	}

	private void printMap() {
		for (int i = 0; i < size; i++) {
			for (int j = 0; j < size; j++) {
				System.out.print(map[i][j] + "  ");
			}
			System.out.println();
		}
	}

	private void remakeMap() {
		hMap.setMap(map);
	}

	public HeightMap getMap() {
		return hMap;
	}
}
